import datetime
import uuid

from sqlalchemy import insert, select, update, delete

from apps.user.user_form import PasswordLoginForm, RegisterBaseForm, SearchUserForm, SearchRoleForm, UpdateUserForm
from config import server_config
from config.const import error_code, constant
from apps.user import user_blueprint, user_const
from flask import g, jsonify, request, make_response

from database.db_manager import get_session, db_session
from database.user_model import users, model_columns, DBCustomQuery, split_roles, roles
from forword.custom_error.request_errors import RequestError
from forword.decorators.token_decorator import token_require, admin_token_require
from utils.encrypt_helper import encrypt_util
from utils.everying import tailor_monster
from utils.log import log_api


@user_blueprint.route('/login', methods=["POST"])
def user_login():
    log_api.info('user login params: ' + str(request.json))
    user_login_form = PasswordLoginForm(**request.json)
    user_info = user_login_form.dict().get("user_info")

    token = server_config.token_util.gen_token(user_info["id"])

    log_api.info(
        'user login success with username=%s password=%s' % (user_login_form.username, user_login_form.password))
    return jsonify({"error_code": error_code.CODE_SUCCESS, "data": {"user_info": user_info, "token": token}})


@user_blueprint.route('/user_register', methods=["POST"])
@admin_token_require
def user_register():
    # 注册 validate
    register_form = RegisterBaseForm(**request.json)

    # 创建用户
    user_info = {
        'username': register_form.username,
        "roles": ",".join(register_form.roles),
        'mobile': register_form.mobile,
        'password': encrypt_util.hash(register_form.password),
        'gender': user_const.default_gender,
        'birthday': user_const.default_birthday,
    }

    insert_stmt = users.insert().values(user_info)

    result = db_session().execute(insert_stmt)
    # 收到影响的行数
    # inserted_rows = result.rowcount
    db_session().commit()
    log_api.info(f"register user, data={register_form.dict()}")

    token = server_config.token_util.gen_token(result.inserted_primary_key[0])
    user_info["id"] = result.inserted_primary_key[0]
    return jsonify({"error_code": error_code.CODE_SUCCESS, "data": {"user_info": user_info, "token": token}})


@user_blueprint.route('/')
@token_require
def get_user_info():
    user_id = g.user_id

    user = db_session().execute(
        select(users).where(users.c.id == user_id)).fetchone()
    if not user:
        raise RequestError("用户不存在")
    user_info = dict(user)
    user_info = tailor_monster.format_datetime(user_info)
    del user_info["password"]
    user_info["roles"] = user_info["roles"].split(",")

    return jsonify({"error_code": error_code.CODE_SUCCESS, "data": {"user_info": user_info}})


# user_list
@user_blueprint.route('/user_list')
@admin_token_require
def get_user_list():
    search_form = SearchUserForm(**request.args)
    sql_model = DBCustomQuery(users, ["password"]).filter_deleted()

    if search_form.search:
        sql_model = sql_model.where(users.c.username.like(r'%{}%'.format(search_form.search)))

    user_list = list(
        map(
            lambda x: dict(x),
            sql_model.paginate(search_form.page_num, search_form.page_size).fetchall()
        )
    )
    split_roles(user_list)

    count_sql_model = DBCustomQuery(users, ["password"]).filter_deleted()
    if search_form.search:
        count_sql_model = count_sql_model.where(users.c.username.like(r'%{}%'.format(search_form.search)))
    count = count_sql_model.count().scalar()
    return jsonify({"error_code": error_code.CODE_SUCCESS, "data": {"user_list": user_list, "count": count}})


@user_blueprint.route('/role_list')
@admin_token_require
def get_role_list():
    search_form = SearchRoleForm(**request.args)
    sql_model = DBCustomQuery(roles, ["password"])

    if search_form.search:
        sql_model = sql_model.where(users.c.username.like(r'%{}%'.format(search_form.search)))

    roles_list = list(
        map(
            lambda x: dict(x),
            sql_model.paginate(search_form.page_num, search_form.page_size).fetchall()
        )
    )
    split_roles(roles_list)

    return jsonify({"error_code": error_code.CODE_SUCCESS, "data": {"roles_list": roles_list}})


# user_update
@user_blueprint.route('/user_update', methods=["PATCH"])
@admin_token_require
def update_user():
    update_form = UpdateUserForm(**request.json)

    update_dict = dict(filter(lambda up: up[1], update_form.dict().items()))
    update_dict["roles"] = ",".join(update_dict["roles"])
    update_dict["password"] = encrypt_util.hash(update_dict["password"])
    del update_dict["id"]
    # result.rowcount
    upt = update(users).where(users.c.id == update_form.id).values(**update_dict)
    db_session().execute(upt)
    db_session().commit()
    print(update_form)

    return jsonify({"error_code": error_code.CODE_SUCCESS, "msg": "更新成功"})


@user_blueprint.route('/', methods=["DELETE"])
@admin_token_require
def del_user():
    del_user_id = request.args.get("id")

    upt = update(users).where(users.c.id == del_user_id).values(**{"deleted_at": datetime.datetime.now()})
    db_session().execute(upt)
    db_session().commit()

    return jsonify({"error_code": error_code.CODE_SUCCESS, "msg": "删除成功"})
